﻿using System;
using System.Collections;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using SilverlightStudentManager.StudentServiceReference;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Input;
using System.ComponentModel.DataAnnotations;
using SilverlightStudentManager.Validators;
using FluentValidation;
using System.Linq;

namespace SilverlightStudentManager.ViewModels
{
    public class InformationViewModel : ViewModelBase//, IDataErrorInfo
    {

        private InformationClient infomationclient = new InformationClient();
        private readonly AbstractValidator<Infomation> validator = new InformationValidator();        

        public InformationViewModel()
        {
            this.RefreshInformation();
            this.saveinformation = new SaveCurrentImformation(this);
        }

        private void RefreshInformation()
        {
            this.infomationclient.GetByAllInformationCompleted += (s, e) =>
                {
                    this.Informations = e.Result;
                };
            this.infomationclient.GetByAllInformationAsync();
        }

        #region [DataFiels]

        private Infomation newinformation = new Infomation();

        private const string FirstNameProperty = "FirstName";
        public string FirstName
        {
            get
            {
                return this.newinformation.FirstName;
            }

            set
            {                
                this.newinformation.FirstName = value;
                OnPropertyChanged(FirstNameProperty);

                ClearError(FirstNameProperty);
                var validationResult = validator.Validate(this.newinformation, FirstNameProperty);
                if (!validationResult.IsValid)
                    validationResult.Errors.ToList().ForEach(x => SetError(FirstNameProperty, x.ErrorMessage));
            }
        }

        private const string LastNameProperty = "LastName";
        public string LastName
        {
            get
            {
                return this.newinformation.LastName;
            }

            set
            {
                this.newinformation.LastName = value;
                OnPropertyChanged(LastNameProperty);

                ClearError(LastNameProperty);
                var validationResult = validator.Validate(this.newinformation, LastNameProperty);
                if (!validationResult.IsValid)
                    validationResult.Errors.ToList().ForEach(x => SetError(LastNameProperty, x.ErrorMessage));
            }
        }

        private const string PhoneProperty = "Phone";
        public string Phone
        {
            get
            {
                return this.newinformation.Phone;
            }

            set
            {
                this.newinformation.Phone = value;
                OnPropertyChanged(PhoneProperty);

                ClearError(PhoneProperty);
                var validationResult = validator.Validate(this.newinformation, PhoneProperty);
                if (!validationResult.IsValid)
                    validationResult.Errors.ToList().ForEach(x => SetError(PhoneProperty, x.ErrorMessage));
            }
        }

        private const string LocalProperty = "Local";
        public string Local
        {
            get
            {
                return this.newinformation.Local;
            }

            set
            {
                this.newinformation.Local = value;
                OnPropertyChanged(LocalProperty);

                ClearError(LocalProperty);
                var validationResult = validator.Validate(this.newinformation, LocalProperty);
                if (!validationResult.IsValid)
                    validationResult.Errors.ToList().ForEach(x => SetError(LocalProperty, x.ErrorMessage));
            }
        }

        private const string BirthdayProperty = "Birthday";
        public DateTime? Birthday
        {
            get
            {
                return this.newinformation.Birthday;
            }

            set
            {
                this.newinformation.Birthday = value;
                OnPropertyChanged(BirthdayProperty);

                ClearError(BirthdayProperty);
                var validationResult = validator.Validate(this.newinformation, BirthdayProperty);
                if (!validationResult.IsValid)
                    validationResult.Errors.ToList().ForEach(x => SetError(BirthdayProperty, x.ErrorMessage));
            }
        }

        #endregion

        private IEnumerable<Infomation> informations;
        public IEnumerable<Infomation> Informations
        {
            get
            { 
                return this.informations;
            }

            set
            {
                this.informations = value;
                this.OnPropertyChanged("Informations");
            }
        }

        private Infomation currentinformation;
        public Infomation CurrentInformation
        { 
            get
            {
                return this.currentinformation;
            }

            set
            {
                this.currentinformation = value;
                this.newinformation = this.currentinformation;
                this.OnPropertyChanged("CurrentInformation");

                if (this.currentinformation == null)
                {
                    this.newinformation = new Infomation();
                    //this.OnPropertyChanged("CurrentInformation");
                    //this.OnPropertyChanged("FirstName");
                    //this.OnPropertyChanged("LastName");
                    //this.OnPropertyChanged("Phone");
                    //this.OnPropertyChanged("Local");
                    //this.OnPropertyChanged("Birthday");        
                }
                else

                    this.RefreshToViewErrors();
                //this.OnPropertyChanged("FirstName");
                //this.OnPropertyChanged("LastName");
                //this.OnPropertyChanged("Phone");
                //this.OnPropertyChanged("Local");
                //this.OnPropertyChanged("Birthday");  
                    
            }
        }

        private void UpdateCurrentInformation()
        {
            if (!this.HasErrors)
            {
                this.infomationclient.UpdateInformationCompleted += (s, e) =>
                    {
                        this.Message = "Update " + e.Result.ToString();
                    };
                this.infomationclient.UpdateInformationAsync(this.CurrentInformation);
            }
        }

        private void DeleteInformation()
        {
            if (!this.HasErrors)
            {
                this.infomationclient.DeleteIformationCompleted += (s, e) =>
                {
                    this.Message = "Delete " + e.Result.ToString();
                    if (e.Result)
                    {
                        this.RefreshInformation();
                    }
                };
                this.infomationclient.DeleteIformationAsync(this.currentinformation.ID.ToString());
            }
        }

        private void InsertInformation()
        {
            RefreshToViewErrors();
            if (!this.HasErrors)
            {
                this.infomationclient.InsertInformationCompleted += (s, e) =>
                {
                    this.Message = "Insert " + e.Result.ToString();
                    if (e.Result) this.RefreshInformation();
                };
                this.infomationclient.InsertInformationAsync(this.newinformation);
            }
        }

        private void RefreshToViewErrors()
        {
            this.FirstName = this.newinformation.FirstName;
            this.LastName = this.newinformation.LastName;
            this.Birthday = this.newinformation.Birthday;
            this.Phone = this.newinformation.Phone;
            this.Local = this.newinformation.Local;

        }

        private void ResetDataFiels()
        {
            this.OnPropertyChanged("CurrentInformation");
            this.OnPropertyChanged("FirstName");
            this.OnPropertyChanged("LastName");
            this.OnPropertyChanged("Phone");
            this.OnPropertyChanged("Local");
            this.OnPropertyChanged("Birthday");  
        }

        private SaveCurrentImformation saveinformation;
        public SaveCurrentImformation SaveInfomation
        {
            get
            {
                return this.saveinformation;
            }       
        }

        private string message;
        public string Message
        {
            get
            {
                return this.message;
            }

            set
            {
                this.message = value;
                OnPropertyChanged("Message");
            }
        }

        public class SaveCurrentImformation : ICommand
        {

            private InformationViewModel viewmodel;
            public SaveCurrentImformation(InformationViewModel viewmodel)
            {
                this.viewmodel = viewmodel;
                this.viewmodel.PropertyChanged += (s, e) =>
                    {
                        if (this.CanExecuteChanged != null)
                        {
                            this.CanExecuteChanged(this, new EventArgs());
                        }
                    };
            }

            public bool CanExecute(object parameter)
            {
                if (parameter.ToString() == "Insert")
                    return true;
                else
                    return this.viewmodel.CurrentInformation != null;
            }

            public event EventHandler CanExecuteChanged;

            public void Execute(object parameter)
            {
                switch (parameter.ToString())
                {
                    case "Update": this.viewmodel.UpdateCurrentInformation();
                        break;
                    case "Delete": this.viewmodel.DeleteInformation();
                        break;
                    case "Insert": this.viewmodel.InsertInformation();
                        break;
                    default: break;
                }
                
               // this.viewmodel.Message = parameter.ToString();
            }
        }

        //public string Error
        //{
        //    get { return null; }
        //}

        //public string this[string columnName]
        //{
        //    get
        //    {
        //        int x;
        //        this.Message = columnName;
        //        if (columnName == "Phone")
        //        {
        //            if (Int32.TryParse( this.newinformation.Phone.ToString(), out x))
        //            {
        //                //this.iserror = true;
        //                return "ABC";
        //            }
        //            else
        //            {
        //                //this.iserror = false;
        //            }
        //        }
        //        return null;
        //    }

        //}
    }
}
